package com.dc.service;

import java.io.IOException;
import java.util.List;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;

import redis.clients.jedis.Jedis;
import core.Constants;
import core.dto.MarketDTO;
import core.service.URLService;
import core.util.JedisUtil;
import core.util.SerializeUtil;

public class ReloadService implements InitializingBean, Runnable {
	private static Logger logger = LoggerFactory.getLogger(ReloadService.class);
	
	private URLService urlService;
	
	@Override
	public void afterPropertiesSet() throws Exception {
		new Thread(this).start();
	}
	
	public void setUrlService(URLService urlService) {
		this.urlService = urlService;
	}

	@Override
	public void run() {
		logger.info("===================================");
		logger.info("======== Init Data Center Begin ===");
		logger.info("===================================");
		long start = System.currentTimeMillis();
		reloadBtcLtcPrice();
		//reloadAllMarkets();
		//reloadMarketInfo();
		//reloadMarketChartDetail();
		reloadMarketOrderDetail();
		long end = System.currentTimeMillis();
		logger.info("Init Data Center Totally Cost: {}s", (end - start) / 1000);
		logger.info("===================================");
		logger.info("======== Init Data Center End =====");
		logger.info("===================================");
	}
	
	public void reloadBtcLtcPrice() {
		logger.info("********** reloadBtcPrice start *************");
		String btcPrice = "" + urlService.getBtcPrice();
		String ltcPrice = "" + urlService.getLtcPrice();
		Jedis jedis = JedisUtil.getJedis();
		try {
			jedis.hset(Constants.PriceMap.name, Constants.PriceMap.btcPrice, btcPrice);
			jedis.hset(Constants.PriceMap.name, Constants.PriceMap.ltcPrice, ltcPrice);
			logger.info("reload btc/ltc price successfully");
		} finally {
			JedisUtil.returnJedis();
		}
		logger.info("********** reloadBtcPrice end *************");
	}
	
	public void reloadAllMarkets() {
		logger.info("********** reloadAllMarkets start *************");
		Jedis jedis = JedisUtil.getJedis();
		double btcPrice = Double.valueOf(jedis.hget(Constants.PriceMap.name, Constants.PriceMap.btcPrice));
		double ltcPrice = Double.valueOf(jedis.hget(Constants.PriceMap.name, Constants.PriceMap.ltcPrice));
		List<MarketDTO> allMarkets = urlService.getAllMarkets(btcPrice, ltcPrice);
		for (MarketDTO market : allMarkets) {
			jedis.zadd(Constants.marketIds, Double.valueOf(market.getMarketid()), market.getMarketid());
		}
		try {
			jedis.set(Constants.allMarkets, SerializeUtil.serialize(allMarkets));
			logger.info("reload all markets successfully");
		} catch (IOException e) {
			logger.error(e.getMessage(), e);
		} finally {
			JedisUtil.returnJedis();
		}
		logger.info("********** reloadAllMarkets end *************");
	}
	
	public void reloadMarketInfo() {
		logger.info("********** reloadMarketInfo start *************");
		Jedis jedis = JedisUtil.getJedis();
		double btcPrice = Double.valueOf(jedis.hget(Constants.PriceMap.name, Constants.PriceMap.btcPrice));
		double ltcPrice = Double.valueOf(jedis.hget(Constants.PriceMap.name, Constants.PriceMap.ltcPrice));
		try {
			int start = 0;
			String step = jedis.hget(Constants.StepMap.name, Constants.StepMap.marketInfo);
			if (step != null) {
				start = Integer.valueOf(step);
			}
			Set<String> markeIds = jedis.zrange(Constants.marketIds, start, -1);
			for (String marketId : markeIds) {
				MarketDTO market = urlService.getMarketInfo(marketId, btcPrice, ltcPrice);
				byte[] key = (Constants.MarketInfoMap.keyPrefix + marketId).getBytes();
				jedis.hset(Constants.MarketInfoMap.name, key, SerializeUtil.serialize(market));
				start++;
				jedis.hset(Constants.StepMap.name, Constants.StepMap.marketInfo, "" + start);
				logger.info("reload market({}) info successfully", marketId);
			}
			jedis.hset(Constants.StepMap.name, Constants.StepMap.marketInfo, "0");
		} catch (IOException e) {
			logger.error(e.getMessage(), e);
		} finally {
			JedisUtil.returnJedis();
		}
		logger.info("********** reloadMarketInfo end *************");
	}
	
	public void reloadMarketOrderDetail() {
		logger.info("********** reloadMarketOrderDetail start *************");
		Jedis jedis = JedisUtil.getJedis();
		try {
			int start = 0;
			String step = jedis.hget(Constants.StepMap.name, Constants.StepMap.tradeOrder);
			if (step != null) {
				start = Integer.valueOf(step);
			}
			Set<String> markeIds = jedis.zrange(Constants.marketIds, start, -1);
			for (String marketId : markeIds) {
				String rawBuy = urlService.getRawBuyOrders(marketId);
				jedis.hset(Constants.BuyOrdersMap.name, Constants.BuyOrdersMap.keyPrefix + marketId, rawBuy);
				logger.info("reload market({}) buy order successfully", marketId);
				
				String rawSell = urlService.getRawSellOrders(marketId);
				jedis.hset(Constants.SellOrdersMap.name, Constants.SellOrdersMap.keyPrefix + marketId, rawSell);
				logger.info("reload market({}) sell order successfully", marketId);
				
				String rawHis = urlService.getRawHisOrders(marketId);
				jedis.hset(Constants.HisOrdersMap.name, Constants.HisOrdersMap.keyPrefix + marketId, rawHis);
				logger.info("reload market({}) his order successfully", marketId);
				
				start++;
				jedis.hset(Constants.StepMap.name, Constants.StepMap.tradeOrder, "" + start);
			}
			jedis.hset(Constants.StepMap.name, Constants.StepMap.tradeOrder, "0");
		} finally {
			JedisUtil.returnJedis();
		}
		logger.info("********** reloadMarketOrderDetail end *************");
	}
	
	public void reloadMarketChartDetail() {
		logger.info("********** reloadMarketChartDetail start *************");
		Jedis jedis = JedisUtil.getJedis();
		try {
			int start = 0;
			String step = jedis.hget(Constants.StepMap.name, Constants.StepMap.tradeChart);
			if (step != null) {
				start = Integer.valueOf(step);
			}
			Set<String> markeIds = jedis.zrange(Constants.marketIds, start, -1);
			for (String marketId : markeIds) {
				String charContent = urlService.getRawMarketChart(marketId);
				jedis.hset(Constants.MarketChartMap.name, Constants.MarketChartMap.keyPrefix + marketId, charContent);
				jedis.hset(Constants.StepMap.name, Constants.StepMap.tradeChart, "" + start);
				start++;
				logger.info("reload market({}) chart successfully", marketId);
			}
			jedis.hset(Constants.StepMap.name, Constants.StepMap.tradeChart, "0");
		} finally {
			JedisUtil.returnJedis();
		}
		logger.info("********** reloadMarketChartDetail end *************");
	}
	
	public static void main(String[] args) {
		Jedis jedis = JedisUtil.getJedis();
		jedis.set("hello", "world");
		System.out.println(jedis.get("hello"));
		JedisUtil.returnJedis();
	}
}
